home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Adobe Graphics & Publishing SDK 1996 December
/
Adobe Graphics & Publishing SDK 1996 December.iso
/
mac
/
Premiere 4.2 SDK r3 Mac
/
Examples
/
Projects
/
Device
/
Device.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-25
|
10KB
|
236 lines
//========================================================================================
//
// Device.c - A skeleton device control module.
//
// Written by Randy Ubillos and Bryan K. "Beaker" Ressler.
//
// Copyright ⌐ 1993-96, Adobe Systems Incorporated, all rights reserved worldwide.
//
// Version 1.00 10/20/93 Original version.
// Version 1.01 9/12/94 Updated for 4.0.
// Version 1.02 11/8/95 Updated for 4.2 and CW7 - Added dsQuiet, cmdJog, and
// cmdEject, fDrvrQuiet, fHasJogMode, fHasEject.
//
//========================================================================================
//========================================================================================
// Includes - use precompiled headers if compiling with CodeWarrior.
//========================================================================================
#ifdef __MWERKS__
#ifdef powerc
#include "PremierePPC"
#else
#include "Premiere68k"
#endif
#else
#include "Premiere.h"
#endif
//========================================================================================
// Types
//========================================================================================
typedef struct {
short mode; // The "last reported mode" our device was in.
} LocalRec, **LocalHand;
//========================================================================================
// Static prototypes
//========================================================================================
static void DisplayAlert(short errNum, DeviceHand theData, LocalHand ldata);
static short CheckConnection(LocalHand ldata);
//========================================================================================
// Process commands to the device
//========================================================================================
pascal short main (short selector, DeviceHand theData)
{
short result = 0;
LocalHand ldata;
switch (selector) {
case dsInit:
// Create any local data here and return an error if could not complete. You
// might put a dialog for parameters here as well. This message is sent when
// user chooses a new device.
// Allocate our locals handle and stuff it into theData. This will persist
// across calls.
(*theData)->deviceData = NewHandleClear(sizeof(LocalRec));
if ((*theData)->deviceData == nil)
result = MemError();
ldata = (LocalHand)(*theData)->deviceData;
// Set up any default values in the local data handle
if (result == noErr && ldata) {
(*ldata)->mode = modeStop;
}
// Attempt the default connection to the device.
if (result == noErr)
result = CheckConnection(ldata);
// Now that we've got a connection to our device, send ourselves a setup
// message.
if (result == noErr)
result = main(dsSetup, theData);
break;
case dsRestart:
// This message is the same as dsInit, exept the data handle has already been
// filled in (from data saved in a project file or the preferences file). You
// should verify the device connection, and open any needed drivers. This mes-
// sage is sent when restarting Premiere.
ldata = (LocalHand)(*theData)->deviceData;
result = CheckConnection(ldata);
if (result != noErr)
DisplayAlert(1, theData, ldata);
break;
case dsSetup:
// This message is sent when the user clicks the "Options╔" button in the
// Device Control preferences dialog. Return a non-zero value if the new set-
// tings fail (for instance, if they specify a different device and CheckCon-
// ection fails for that new device, return a non-zero value).
break;
case dsQuiet:
// Disconnect from the device, but don't dispose of allocated structures yet.
// You'll get a dsCleanup for that.
break;
case dsCleanup:
// Here is where we dispose of anything we allocated and close drivers that we
// opened. This message is sent at quit time.
DisposHandle((*theData)->deviceData);
break;
case dsExecute:
// This message is where we perform actual device control and device inquiry
// tasks. Cache up ldata and then act based on the command.
ldata = (LocalHand)(*theData)->deviceData;
switch ((*theData)->command) {
case cmdGetFeatures:
// Here's where we tell Premiere about the features this device has.
// We can OR as many of these together as apply.
(*theData)->features = fBasic + fRecord + fCanShuttle + fCanJog +
fDrvrQuiet + fHasJogMode + fCanEject;
break;
case cmdStatus:
// Premiere wants to know the current status of the device we're con-
// nected to. Often it is not possible to instantly know the status of
// a device. Premiere does cmdStatus calls all the time, and it
// behooves the DevC not to waste any time here. The way some of the
// built-in Premiere modules handle this is by keeping a "last record-
// ed mode/location" value in their local data, and they use asynch-
// ronous calls to their drivers. Each time into cmdStatus, if the
// last async status call you made to your driver is ready, you copy
// the mode and location into your "last recorded" values. If there's
// not a status call queued up, go ahead and queue one up to your
// driver. Finally, at the end of each cmdStatus call, just return
// your last-recorded mode and location.
(*theData)->timeformat = 0; // 0: non-drop, 1: drop-frame
(*theData)->timerate = 30; // 24, 25 and 30 are valid
(*theData)->timecode = 0; // Current device location
(*theData)->mode = modeStop; // Current mode
break;
case cmdNewMode:
// Here Premiere wants you to change the device into a new mode. If we
// can't do it, the next cmdStatus call will reflect the old mode.
// Normally you send the commands to the device here, even if they are
// asynchronous.
(*ldata)->mode = (*theData)->mode;
break;
case cmdGoto:
// Premiere is telling you to move the device to the timecode spec-
// ified in theData. Usually you start the device searching and return
// without waiting for it to finish. Then Premiere will hammer
// cmdStatus until the time matches the requested time. When the deck
// is searching, your cmdStatus should return the mode as "modeGoto",
// which will result in the text "Searching..." showing up in the
// timecode display. This is the sorta lame, let-Premiere-do-the-work
// way of doing timecode location -- if you can do cmdLocate, do it.
// Do whatever's necessary to move the device to (*theData)->timecode.
break;
case cmdLocate:
// This is the synchronous way of doing timecode location. Premiere
// wants you to move the deck to the specified timecode and return
// with the deck in play mode rolling over timecode. You should use
// the most accurate positioning you can here. Remember that you can
// send yourself cmdStatus messages to find out what time your over.
// Often you'll use some "rough seek" command to get your self within
// a second or two before the requested code, then send yourself a
// cmdNewMode to go into play mode. Then you sit in a tight loop
// sending yourself cmdStatus messages until the time is equal to the
// requested timecode, then you return as fast as possible. Don't try
// to compensate for the latency between when you return and when
// video actually gets captured. This is not really within your con-
// trol, and Premiere has a calibration feature to take care of that
// for you (by providing a preroll value).
break;
case cmdShuttle:
// Here Premiere is telling you to shuttle the deck either forward
// or backward at a certain speed (the value is in (*theData)->mode).
// -100 means 2x backwards playback, -50 means 1x backwards playback,
// 0 means pause, 50 means 1x forward playback, and 100 means 2x
// forwards playback. You may have to tweak this mapping to get the
// right feel.
break;
case cmdJogTo:
// Here Premiere is telling you to quickly locate the deck at
// (*theData)->timecode. That time will never be far from where you
// currently are. The value for timecode is calculated by the distance
// the user dragged the tractor tread on the screen.
break;
case cmdJog:
// Here Premiere is telling you to jog at a rate specified in 'mode',
// from -25 to +25.
break;
case cmdEject:
// Here Premiere tells you to eject the media.
break;
}
break;
}
return(result);
}
//========================================================================================
// Put up an error message
//========================================================================================
static void DisplayAlert(short errNum, DeviceHand theData, LocalHand ldata)
{
#ifdef applec
#pragma unused(errNum, theData, ldata)
#endif
(*(**theData).PauseProc)(); // Pause the main program
// Put up the proper alert box here
(*(**theData).ResumeProc)(); // Restart the main program
}
//========================================================================================
// Check the device connection
//========================================================================================
static short CheckConnection(LocalHand ldata)
{
#ifdef applec
#pragma unused(ldata)
#endif
// Check the device specified in 'ldata' and return 0 if connection is OK, non-zero
// otherwise.
return(0);
}